/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package testkryo.impl;

import com.esotericsoftware.kryo.Kryo;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.logging.Level;
import java.util.logging.Logger;
import testkryo.BufferUtil;

/**
 *
 * @author takao
 */
public class KryoIndex {

  private Path indexPath = Paths.get("src/index");
  private Path indexFile;
  private Kryo kryo;
  private Class clazz;

  public KryoIndex(Kryo kryo, Class clazz) {
    this.kryo = kryo;
    this.clazz = clazz;
    kryo.register(Long[].class);
    indexFile = indexPath.resolve(clazz.getName() + ".index");
    try {
      Files.createFile(indexFile);
    } catch (FileAlreadyExistsException fx) {
    } catch (IOException ex) {
      Logger.getLogger(KryoIndex.class.getName()).log(Level.SEVERE, null, ex);
    }
  }

  public Long[] get(long id) {
    Long[] ll = null;
    FileChannel fc = null;
    long pos = id * 25;

    try {
      fc = FileChannel.open(indexFile, StandardOpenOption.READ, StandardOpenOption.WRITE);

      fc.position(pos);

      ByteBuffer buffer = ByteBuffer.allocate(25);

      fc.read(buffer);
      buffer.flip();
      if (buffer.limit() > 0) {
        ll = kryo.readObject(buffer, Long[].class);
      }
    } catch (IOException ex) {
      Logger.getLogger(KryoIndex.class.getName()).log(Level.SEVERE, null, ex);
    } finally {
      if (fc != null) {
        try {
          fc.close();
        } catch (IOException ex) {
          Logger.getLogger(KryoIndex.class.getName()).log(Level.SEVERE, null, ex);
        }
      }
    }
    return ll;
  }

  public void put(long id, Long[] oldll, Long[] ll) {
    ByteBuffer buffer = ByteBuffer.allocate(25);
//    ByteBuffer testBuffer1 = ByteBuffer.allocate(25);
//    ByteBuffer testBuffer2 = ByteBuffer.allocate(25);
    FileChannel fc = null;
    kryo.writeObject(buffer, ll);
//    kryo.writeObject(testBuffer1, oldll);
    buffer.flip();
//    testBuffer1.flip();
    try {
      fc = FileChannel.open(indexFile, StandardOpenOption.READ, StandardOpenOption.WRITE);
      fc.position(id * 25);
//      fc.read(testBuffer2);
//      testBuffer2.flip();
//      fc.position(id * 25);

//      if (testBuffer1.equals(testBuffer2)) {
//        System.out.println("SUCCESS " + Thread.currentThread().getName());
      fc.write(buffer);
//      } else {
//        System.out.println("FAIL " + Thread.currentThread().getName());
//      }
    } catch (IOException ex) {
      Logger.getLogger(KryoIndex.class.getName()).log(Level.SEVERE, null, ex);
    } finally {
      if (fc != null) {
        try {
          fc.close();
        } catch (IOException ex) {
          Logger.getLogger(KryoIndex.class.getName()).log(Level.SEVERE, null, ex);
        }
      }
    }
  }
}
